#import <OpenGLES/EAGL.h>
#import <OpenGLES/EAGLDrawable.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <Foundation/NSPathUtilities.h>
#import <Foundation/NSUserDefaults.h>


#include <pthread.h>
#include <sys/time.h>
#include "Defines.h"
#include "CGame.h"

extern "C" void EAGLViewBeginRender();
extern "C" void EAGLViewEndRender();

extern "C" unsigned long OS_GetTime()
{
    struct timeval	cur_time;
    gettimeofday(&cur_time, 0);

    return (cur_time.tv_sec*1000 + cur_time.tv_usec/1000);
}

extern "C" const char* GetRealFilePath(const char* filename)
{
	NSString* logic_path = [[NSString alloc] initWithUTF8String: filename];
	NSString* real_path = [[NSBundle mainBundle] pathForResource: logic_path ofType: @""];
	
    if (real_path == nil)
    {
        NSArray   *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString  *documentsDirectory = [paths objectAtIndex:0];  
        
        real_path = [NSString stringWithFormat:@"%@/%@", documentsDirectory,logic_path];
    }
    
    const char* ret = [real_path UTF8String];
    [logic_path release];
	
    return ret;
}

/*
extern "C" bool SaveAppData(const char* filename, const char* data_to_save, int data_length)
{
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	
	if (!documentsDirectory) 
	{
		NSLog(@"Documents directory not found!");
		return NO;
    }
	
	NSString* fname = [[NSString alloc] initWithUTF8String: filename];
	NSString *appfilename = [documentsDirectory stringByAppendingPathComponent:fname];
	
	NSData *appdata = [[NSData alloc] initWithBytes: data_to_save length: data_length];
	
	return ([appdata writeToFile:appfilename atomically:YES]);
}
*/

extern "C" bool SaveAppData(const char* filename, const char* data_to_save, int data_length, bool is_append)
{
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	
	if (!documentsDirectory) 
	{
		NSLog(@"Documents directory not found!");
		return NO;
    }
	
	NSString* fname = [[NSString alloc] initWithUTF8String: filename];
	NSString *appfilename = [documentsDirectory stringByAppendingPathComponent:fname];
	
	FILE* stream = NULL;
	if (is_append)
	{
		stream = fopen([appfilename UTF8String], "ab");
	}
	else
	{
		stream = fopen([appfilename UTF8String], "wb");
	}

	if (stream != NULL)
	{
		fwrite(data_to_save, sizeof(BYTE), data_length, stream);
	}
	else
	{
		return false;
	}

	fclose(stream);
	
	return true;
}


extern "C" int ReadAppData(const char* filename, char* &readed_data)
{	
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	
	if (!documentsDirectory) 
	{
		NSLog(@"Documents directory not found!");
		return 0;
    }
	
	NSString* fname = [[NSString alloc] initWithUTF8String:filename];
	NSString *appfilename = [documentsDirectory stringByAppendingPathComponent:fname];
	
	NSData *appdata = [[[NSData alloc] initWithContentsOfFile:appfilename] autorelease];
	
	int size = [appdata length];
	readed_data = new char[size];
	
	[appdata getBytes:readed_data length:size];
	
	return size;
}

extern "C" bool DeleteAppData(const char* filename)
{
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	
	if (!documentsDirectory) 
	{
		NSLog(@"Documents directory not found!");
		return NO;
    }
	
	NSString* fname = [[NSString alloc] initWithUTF8String: filename];
	NSString *appfilename = [documentsDirectory stringByAppendingPathComponent:fname];
	
	if (remove([appfilename UTF8String]) != 0)
	{
		return false;
	}
		
	return true;
}


bool g_isAppExit = false;
CGame* g_pGame = NULL;
//init game
extern "C" void GameInit()
{
	//game init
	g_pGame = new CGame();	
	g_pGame->Init();
}

//run
extern "C" void GameRun()
{	
	EAGLViewBeginRender();
	
	g_pGame->Run();
	
	if (g_pGame->_isExit == true)
	{
		g_isAppExit = true;
	}
	
	EAGLViewEndRender();
}

//pause
extern "C" void GamePause()
{	
	g_pGame->Pause();
}

//resume
extern "C" void GameResume()
{
	if (g_pGame != NULL)
	{
		g_pGame->Resume();
	}
}

void JoinThread();

//end game
extern "C" void GameExit()
{
	//release res
	g_pGame->Exit();
	g_pGame->Release();
	SAFE_DEL(g_pGame);
	g_isAppExit = true;
	
	JoinThread();
}

pthread_t g_thread_id;
void* ThreadRun(void* param);


extern "C" void StartThread()
{
	if (pthread_create(&g_thread_id, NULL, &ThreadRun, NULL)) 
	{
		exit(1);
	}
}

void* ThreadRun(void* param)
{
	//init game
	GameInit();

	while (g_isAppExit == false)
	{
		GameRun();
	}
	
	GameExit();
	
	return 0;
}

void JoinThread()
{
	if (pthread_join(g_thread_id, NULL))
	{
		exit(1);
	}
	exit(0);
}


extern "C" void UpdateTouchBegan(int touchId, int x, int y)
{
	short tmp;
	//change coordinator
	switch (g_pGame->_device_orientation)
	{
		case ORIENTATION_LANDSCAPE_90:
			tmp = x;
			x = k_SCREEN_HEIGHT - y;
			y = tmp;
			break;
			
		case ORIENTATION_LANDSCAPE_270:
			tmp = y;
			y = k_SCREEN_HEIGHT - x;
			x = tmp;
			break;
	}
	
	//call process multi touch
	g_pGame->NotifyTouchesBegan(touchId, x, y, 1);
}

extern "C" void UpdateTouchEnded(int touchId, int x, int y)
{
	short tmp;
	//change coordinator
	switch (g_pGame->_device_orientation)
	{
		case ORIENTATION_LANDSCAPE_90:
			tmp = x;
			x = k_SCREEN_HEIGHT - y;
			y = tmp;
			break;
			
		case ORIENTATION_LANDSCAPE_270:
			tmp = y;
			y = k_SCREEN_HEIGHT - x;
			x = tmp;
			break;
	}
	
	//call process multi touch
	
	g_pGame->NotifyTouchesEnd(touchId, x, y, 1);
}

extern "C" void UpdateTouchMoved(int touchId, int x, int y)
{
	short tmp;
	//change coordinator
	switch (g_pGame->_device_orientation)
	{
		case ORIENTATION_LANDSCAPE_90:
			tmp = x;
			x = k_SCREEN_HEIGHT - y;
			y = tmp;
			break;
			
		case ORIENTATION_LANDSCAPE_270:
			tmp = y;
			y = k_SCREEN_HEIGHT - x;
			x = tmp;
			break;
	}
	
	//call process multi touch
	g_pGame->NotifyTouchesMoved(touchId, x, y, 1);
}

extern "C" void InitADBanner()
{
    [[CBoxAppAppDelegate sharedInstance] performSelectorOnMainThread:@selector(_InitADBanner:) withObject:nil waitUntilDone:NO];

}

extern "C" void LoadOnlineData(char* name)
{
    NSString* fname = [[NSString alloc] initWithUTF8String: name];
    NSString *server = @"http://115.78.11.16:8080/MonsterAge";
    NSString *stringURL = [NSString stringWithFormat:@"%@/%@", server, fname];
    NSURL  *url = [NSURL URLWithString:stringURL];
    NSData *urlData = [NSData dataWithContentsOfURL:url];
    if ( urlData )
    {
        NSArray   *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString  *documentsDirectory = [paths objectAtIndex:0];  
        
        NSString  *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,fname];
        [urlData writeToFile:filePath atomically:YES];
        const char *bar = [filePath UTF8String];
    }
}


